import wx
import wx.gizmos
from LMG.GUI.Base.dhmtimectrl import DHMTimeCtrl

class TemplatesDialog(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, -1, _("Templates Dialog"))

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.panel = TemplatesPanel(self)
        sizer.Add(self.panel, 1, wx.EXPAND, 0)
        sizer.Add(wx.Button(self, wx.ID_CLOSE, _('Close')), 0, wx.ALIGN_LEFT | wx.ALL, 5)
        self.SetEscapeId(wx.ID_CLOSE)
        self.Bind(wx.EVT_BUTTON, self.onClose, id = wx.ID_CLOSE)
        self.Bind(wx.EVT_CLOSE, self.onClose)

        self.SetAutoLayout(True)
        self.SetSizerAndFit(sizer)
        
    def onClose(self, event):
        utility.labelmanager.reorder(self.panel.list.GetStrings())
        self.panel.options.saveValues()
        utility.labelmanager.save()
        self.EndModal(wx.ID_OK)
        
class TemplatesPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        
        self.list = TemplatesList(self)
        self.options = TemplateOptions(self)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.list, 1, wx.GROW|wx.ALL, 5)
        sizer.Add(self.options, 0, wx.EXPAND|wx.ALL, 5)
        self.list.SetStrings(utility.labelmanager.l_templates)

        self.SetSizer(sizer)
        
    def onSelectionChanged(self):
        self.options.saveValues()
        self.options.loadValues(utility.labelmanager.get(self.list.GetSelection()))
        
class TemplatesList(wx.gizmos.EditableListBox):
    def __init__(self, parent):
        wx.gizmos.EditableListBox.__init__(self, parent, -1, _("Templates"))
        
        self.parent = parent

        self.SetMinSize((-1, 150))
        
        # Events Table
        self.GetListCtrl().Bind(wx.EVT_LIST_ITEM_SELECTED, self.onItemSelected)
        self.GetListCtrl().Bind(wx.EVT_LIST_ITEM_DESELECTED, self.onItemSelected)
        self.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.onEndEdit)
        self.GetDelButton().Bind(wx.EVT_BUTTON, self.onDelete)

    def onItemSelected(self, event):
        """ Template selection change """
        self.parent.onSelectionChanged()
        event.Skip()
        
    def onEndEdit(self, event):
        """ Template renamed """
        oldname = self.GetListCtrl().GetItemText(event.GetIndex())
        newname = event.GetLabel()
        if utility.labelmanager.get(newname) or newname.strip() == "":
            event.Veto()
            return
        if oldname == "":
            utility.labelmanager.new(newname)
        else:
            utility.labelmanager.rename(oldname, newname)
        wx.CallAfter(self.parent.onSelectionChanged)
        event.Skip()
    
    def onDelete(self, event):
        """ Template removed """
        utility.labelmanager.remove(self.GetSelection())
        event.Skip()

    def GetSelection(self):
        selection = self.GetListCtrl().GetFirstSelected()
        if selection >= 0:
            return self.GetListCtrl().GetItemText(selection)
        return ""
    
class TemplateOptions(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.parent = parent
        self.current = None
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.book = wx.Notebook(self, -1)
        if wx.Platform == "__WXMAC__":
            self.book.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
        self.Initialise()
        sizer.Add(self.book, 0, wx.EXPAND, 1)
        self.SetSizer(sizer)

    def Initialise(self):
        """
        Initialzes the options pages.
        """
        self.book.DeleteAllPages()
        
        self.label = LabelPanel(self, _("Label"))
        self.bandwidth = BandwidthPanel(self, _("Bandwidth"))
        self.queue = QueuePanel(self, _("Queue"))
        self.trigger = TriggerRules(self, _("Trigger Rules"))
        
        self.book.AddPage(self.label, self.label.title, True)
        self.book.AddPage(self.bandwidth, self.bandwidth.title, False)
        self.book.AddPage(self.queue, self.queue.title, False)
        self.book.AddPage(self.trigger, self.trigger.title, False)

    def loadValues(self, current):
        self.current = current
        self.label.loadValues()
        self.bandwidth.loadValues()
        self.queue.loadValues()
        self.trigger.loadValues()

    def saveValues(self):
        if self.current:
            self.label.saveValues()
            self.bandwidth.saveValues()
            self.queue.saveValues()
            self.trigger.saveValues()
            

class BasePanel(wx.Panel):
    def __init__(self, parent, title):
        wx.Panel.__init__(self, parent.book, -1)
        self.parent = parent
        self.title = title        
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add((-1,10))
        
    def initTasks(self):
        self.loadValues()
        self.SetSizer(self.sizer)

    def loadValues(self):
        pass

    def saveValues(self):
        pass
    
class BandwidthPanel(BasePanel):
    def __init__(self, *args, **kwargs):
        BasePanel.__init__(self, *args, **kwargs)
        # Max uploads 
        maxuploadsbox = wx.BoxSizer(wx.HORIZONTAL)
        self.maxupsection = wx.CheckBox(self, -1, _("Maximum uploads:"))  
        maxuploadsbox.Add(self.maxupsection, 0, wx.ALIGN_CENTER_VERTICAL)
        maxuploadsbox.Add((-1, -1), 1)
        self.maxupload = wx.SpinCtrl(self, size = wx.Size(60, -1))
        self.maxupload.SetRange(2, 100)
        maxuploadsbox.Add(self.maxupload, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
        self.sizer.Add(maxuploadsbox, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)
        # Upload limit
        maxoverall_up = wx.BoxSizer(wx.HORIZONTAL)
        self.upsection = wx.CheckBox(self, -1, _("Upload rate (KB/s):"))  
        maxoverall_up.Add(self.upsection, 0, wx.ALIGN_CENTER_VERTICAL)
        maxoverall_up.Add((-1, -1), 1)
        self.uploadrate = wx.SpinCtrl(self, size = wx.Size(60, -1))
        self.uploadrate.SetRange(0, 9999)
        maxoverall_up.Add(self.uploadrate, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
        self.sizer.Add(maxoverall_up, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)
        # Download limit
        maxdownoverall_down = wx.BoxSizer(wx.HORIZONTAL)
        self.downsection = wx.CheckBox(self, -1, _("Download rate (KB/s):"))  
        maxdownoverall_down.Add(self.downsection, 0, wx.ALIGN_CENTER_VERTICAL)
        maxdownoverall_down.Add((-1, -1), 1)
        self.downloadrate = wx.SpinCtrl(self, size = wx.Size(60, -1))
        self.downloadrate.SetRange(0, 9999)
        maxdownoverall_down.Add(self.downloadrate, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
        self.sizer.Add(maxdownoverall_down, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)

        self.initTasks()
        
    def loadValues(self):
        t = self.parent.current
        if t is None:
            self.Disable()
            return
        self.Enable()
        if t.maxuploads is not None:
            self.maxupsection.SetValue(True)
            self.maxupload.SetValue(max(2, t.maxuploads))
        else:
            self.maxupsection.SetValue(False)
            self.maxupload.SetValue(utility.config.Read("maxupload", "int"))            
        if t.uploadrate is not None:
            self.upsection.SetValue(True)
            self.uploadrate.SetValue(t.uploadrate)
        else:
            self.upsection.SetValue(False)
            self.uploadrate.SetValue(utility.config.Read("maxuploadrate", "int"))            
        if t.downloadrate is not None:
            self.downsection.SetValue(True)
            self.downloadrate.SetValue(t.downloadrate)
        else:
            self.downsection.SetValue(False)
            self.downloadrate.SetValue(utility.config.Read("maxdownloadrate", "int"))            
            
    def saveValues(self):
        t = self.parent.current
        if t is None:
            return
        if self.maxupsection.GetValue():
            t.maxuploads = self.maxupload.GetValue()
        else:
            t.maxuploads = None
        if self.upsection.GetValue():
            t.uploadrate = self.uploadrate.GetValue()
        else:
            t.uploadrate = None
        if self.downsection.GetValue():
            t.downloadrate = self.downloadrate.GetValue()
        else:
            t.downloadrate = None
    
class QueuePanel(BasePanel):
    def __init__(self, *args, **kwargs):
        BasePanel.__init__(self, *args, **kwargs)

        # Seeding Time
        timesizer = wx.BoxSizer(wx.HORIZONTAL)
        self.seedtimesection = wx.CheckBox(self, -1, _("Seeding Time:"))          
        timesizer.Add(self.seedtimesection, 0, wx.ALIGN_CENTER_VERTICAL)       
        self.cbtime = DHMTimeCtrl(self)
        timesizer.Add((-1,-1), 1)
        timesizer.Add(self.cbtime, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
        timesizer.Add(self.cbtime.GetSpinButton(), 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 2)
        self.sizer.Add(timesizer, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)
        # Seeding Ratio
        ratiosizer = wx.BoxSizer(wx.HORIZONTAL)
        self.seedratiosection = wx.CheckBox(self, -1, _("Seeding Ratio:"))          
        ratiosizer.Add(self.seedratiosection, 0, wx.ALIGN_CENTER_VERTICAL)
        ratioval = ['0', '50', '60', '70', '75', '80', '90', '100', '125', '150', '175', '200', '300', '400', '500']
        self.cbratio = wx.ComboBox(self, -1, "", wx.Point(-1, -1), wx.Size(65, -1), ratioval, wx.CB_DROPDOWN|wx.CB_READONLY)
        ratiosizer.Add((-1,-1), 1)
        ratiosizer.Add(self.cbratio, 1, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
        self.sizer.Add(ratiosizer, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)
        # Timeouts
        timeoutsebox = wx.BoxSizer(wx.HORIZONTAL)
        self.timeoutcheck = wx.CheckBox(self, -1, _('Disable timeouts'))
        timeoutsebox.Add(self.timeoutcheck, 0, wx.ALIGN_CENTER_VERTICAL)
        self.sizer.Add(timeoutsebox, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)                

        self.initTasks()
        
    def loadValues(self):
        t = self.parent.current
        if t is None:
            self.Disable()
            return
        self.Enable()
        if t.uploadtime is not None:
            self.seedtimesection.SetValue(True)
            self.cbtime.SetValue(t.uploadtime)
        else:
            self.seedtimesection.SetValue(False)
            self.cbtime.SetValue(utility.config.Read("uploadtime", "int"))            
        if t.uploadratio is not None:
            self.seedratiosection.SetValue(True)
            self.cbratio.SetValue(str(t.uploadratio))
        else:
            self.seedratiosection.SetValue(False)
            self.cbratio.SetValue(utility.config.Read("uploadratio"))            
        self.timeoutcheck.SetValue(t.distimeouts)
        
    def saveValues(self):
        t = self.parent.current
        if t is None:
            return
        if self.seedtimesection.GetValue():
            cbtime = self.cbtime.GetValue(asInt = True)
            if 0 != cbtime < 1800:
                cbtime = 1800
            t.uploadtime = cbtime
        else:
            t.uploadtime = None
        if self.seedratiosection.GetValue():
            t.uploadratio = self.cbratio.GetValue()
        else:
            t.uploadratio = None
        t.distimeouts = self.timeoutcheck.GetValue()
        
class LabelPanel(BasePanel):
    def __init__(self, *args, **kwargs):
        BasePanel.__init__(self, *args, **kwargs)

        # Hide
        hiddenbox = wx.BoxSizer(wx.HORIZONTAL)
        self.hidden = wx.CheckBox(self, -1, _("Hide label from menu"))
        hiddenbox.Add(self.hidden, 0, wx.ALIGN_CENTER_VERTICAL)
        self.sizer.Add(hiddenbox, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)
        # Active label
        activelabelbox = wx.BoxSizer(wx.HORIZONTAL)
        self.activelabel = wx.CheckBox(self, -1, _("Can be active label"))
        activelabelbox.Add(self.activelabel, 0, wx.ALIGN_CENTER_VERTICAL)
        self.sizer.Add(activelabelbox, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 6)

        self.initTasks()
        
    def loadValues(self):
        t = self.parent.current
        if t is None:
            self.Disable()
            return
        self.Enable()
        self.hidden.SetValue(t.hidelabel)
        self.activelabel.SetValue(t.activelabel)

    def saveValues(self):
        t = self.parent.current
        if t is None:
            return
        t.hidelabel = self.hidden.GetValue()
        t.activelabel = self.activelabel.GetValue()
        
class TriggerRules(BasePanel):
    def __init__(self, *args, **kwargs):
        BasePanel.__init__(self, *args, **kwargs)

        self.switch = wx.CheckBox(self, -1, self.title)
        self.sizer.Add(self.switch, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 6)
        self.sizer.Add((-1,10))
        self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.GROW, 0)

        self.trackernamerule = self.getTriggerRuleBox(_('Tracker name'))        
        self.torrentnamerule = self.getTriggerRuleBox(_('Torrent name'))        
        self.torrentfilenamerule = self.getTriggerRuleBox(_('Torrent filename'))        
        self.receivednamerule = self.getTriggerRuleBox(_('Received filename'))        
        self.initTasks()
        
    def getTriggerRuleBox(self, text):
        rulebox = wx.BoxSizer(wx.HORIZONTAL)
        rule = wx.TextCtrl(self, -1, '', wx.Point(-1, -1), wx.Size(160, -1))
        rulebox.Add(wx.StaticText(self, -1, text+':'), 0, wx.ALIGN_LEFT, 0)
        rulebox.Add((-1,-1), 1)
        rulebox.Add(rule, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        self.sizer.Add(rulebox, 0, wx.EXPAND | wx.LEFT | wx.UP, 5)
        return rule
    
    def loadValues(self):
        t = self.parent.current
        if t is None:
            self.Disable()
            return
        self.Enable()

        self.switch.SetValue(t.trigger)
        
        self.trackernamerule.SetValue(t.triggermatch["Tracker"])
        self.torrentnamerule.SetValue(t.triggermatch["Torrent"])
        self.torrentfilenamerule.SetValue(t.triggermatch["TorrentFile"])
        self.receivednamerule.SetValue(t.triggermatch["File"])
                
    def saveValues(self):
        t = self.parent.current
        if t is None:
            return
        
        t.trigger = self.switch.GetValue()
        
        t.triggermatch["Tracker"] = self.trackernamerule.GetValue()
        t.triggermatch["Torrent"] = self.torrentnamerule.GetValue()
        t.triggermatch["TorrentFile"] = self.torrentfilenamerule.GetValue()
        t.triggermatch["File"] = self.receivednamerule.GetValue()
        
